package com.thx.appserver.servlet;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;

import com.thx.common.util.FileUtil;
import com.thx.common.util.ThreadLocalContext;
import com.thx.common.web.WebConstant;
import com.thx.file.util.WebFileUtil;

public class FileUploadServlet extends HttpServlet{
	private static final long serialVersionUID = 2939261497067604796L;

	protected final Logger logger = Logger.getLogger(getClass());

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
		doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8"); // 设置处理请求参数的编码格式
		resp.setContentType("application/json;charset=UTF-8");
		
		ThreadLocalContext.set(WebConstant.CURRENT_REQUEST, req);
		PrintWriter writer = resp.getWriter();
		
		JSONObject json = new JSONObject();
		InputStream is = null; // 当前上传文件的InputStream对象
	    boolean success = false;
	    int code = 0;
	    String message = "文件上传失败";
	    String fileid = "";
		try {
			DiskFileItemFactory factory = new DiskFileItemFactory();
			factory.setSizeThreshold(4096); // 设置缓冲区大小，这里是4kb
			ServletFileUpload upload = new ServletFileUpload(factory);
			upload.setHeaderEncoding("UTF-8");// 解决上传的文件名乱码
			upload.setSizeMax(100*1024*1024); //设置最大文件尺寸，这里是100MB
			//upload.setSizeMax(4*1024*1024); //设置最大文件尺寸，这里是4MB
			
			String filename = ""; // 上传文件保存到服务器的文件名
			
			List<FileItem> items = upload.parseRequest(req);// 得到所有的文件
			for (Iterator<FileItem> iterator = items.iterator(); iterator.hasNext();) {
				FileItem item = (FileItem) iterator.next();
				if (item.isFormField()){// 处理普通的表单域
					if (item.getFieldName().equals("filename")){
						// 如果新文件不为空，将其保存在filename中
						if (!item.getString().equals("")) filename = item.getString("UTF-8");
					}
				}else if (item.getName() != null && !item.getName().equals("")){// 处理上传文件
					// 从客户端发送过来的上传文件路径中截取文件名
					filename = new String(item.getName().getBytes("UTF-8"));
					filename = filename.substring(filename.lastIndexOf("\\") + 1);
					is = item.getInputStream(); // 得到上传文件的InputStream对象
					
					long size = item.getSize();
					com.thx.file.model.File file = null;
					if(size<(10*1024*1024)){
						file = WebFileUtil.uploadAndSaveFile(filename, input2byte(is));
					}else{
						String newFilePath = WebFileUtil.getFilePath(null);
						String newFileName = FileUtil.rename(filename);
						File tmpfile = saveFile(is,newFilePath + File.separator + newFileName);
						file = saveWebFileUtil(tmpfile,filename);
					}
					
					if(file!=null && StringUtils.isNotBlank(file.getFileId())){
					    success = true;
					    code = 1;
					    message = "文件上传成功";
					    fileid = file.getFileId();
					}else{
						code = 2;
						message = "文件存储失败";
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		    message = "文件上传失败";
		}finally{
	        try {
				json.put("success", success);
		        json.put("code", code);
		        json.put("message", message);
		        json.put("fileid", fileid);
			} catch (JSONException e) {
				e.printStackTrace();
			}
			writer.write(json.toString());
			closeStream(is);
		}
	}
	
	public void closeStream(Closeable stream){
	    try{
	      if (stream != null) stream.close();
	    }catch (IOException e){
	    }
	}
	
	public static final byte[] input2byte(InputStream inStream)
			throws IOException {
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
		byte[] buff = new byte[100];
		int rc = 0;
		while ((rc = inStream.read(buff, 0, 100)) > 0) {
			swapStream.write(buff, 0, rc);
		}
		byte[] in2b = swapStream.toByteArray();
		return in2b;
	}
	
	/**
	 * 保存文件到本地
	 * @param in 输入流
	 * @param path 保存地址
	 * @return boolean 成功标识 
	 * @throws IOException
	 */
	private File saveFile(InputStream in,String path) throws IOException{
		File file = new File(path);
		byte[] buff = new byte[1024];
		int buffLength = -1;
		OutputStream out = null;
		
		try{
			out = new FileOutputStream(file);
			while((buffLength = in.read(buff)) != -1){
				out.write(buff, 0, buffLength);
			}
		}catch(Exception e){
			logger.info(" method saveFile() catch exception by " + e.getMessage());
			e.printStackTrace();
			return null;
		}finally{
			if(out != null){
				out.close();
			}
		}
		return file;
	}
	
	/**
	 * 保存到统一附件存储
	 * @param file
	 * @param oldFileName
	 * @return
	 */
	public static com.thx.file.model.File saveWebFileUtil(File file, String oldFileName) {
		com.thx.file.model.File f = WebFileUtil.saveFile(file, oldFileName);
//		if (f != null) {
//			f.setFileBytes(file.length());
//			return f;
//		}
//		
//		return null;
		return f;
	}
}
